import SockJS from 'sockjs-client'
import Stomp from 'stompjs'

/**
 * WebSocket连接管理类
 */
class WebSocketService {
  constructor() {
    this.stompClient = null
    this.connected = false
    this.subscriptions = new Map()
  }

  /**
   * 连接WebSocket服务器
   * @param {string} url - WebSocket服务器地址，默认使用当前域名
   * @param {Function} onConnected - 连接成功回调
   * @param {Function} onError - 连接错误回调
   */
  connect(url = null, onConnected = null, onError = null) {
    // 如果没有提供URL，使用默认配置
    const wsUrl = url || `${window.location.protocol}//${window.location.host}/ws/notification`
    
    // 创建SockJS连接
    const socket = new SockJS(wsUrl)
    
    // 创建STOMP客户端
    this.stompClient = Stomp.over(socket)
    
    // 连接到服务器
    this.stompClient.connect(
      {},
      (frame) => {
        console.log('WebSocket连接成功:', frame)
        this.connected = true
        if (onConnected) {
          onConnected(frame)
        }
      },
      (error) => {
        console.error('WebSocket连接错误:', error)
        this.connected = false
        if (onError) {
          onError(error)
        }
      }
    )
  }

  /**
   * 订阅主题
   * @param {string} destination - 订阅地址
   * @param {Function} callback - 接收消息的回调函数
   * @returns {string} 订阅ID
   */
  subscribe(destination, callback) {
    if (!this.connected || !this.stompClient) {
      console.error('WebSocket未连接')
      return null
    }

    const subscription = this.stompClient.subscribe(destination, (message) => {
      const body = JSON.parse(message.body)
      callback(body)
    })

    // 保存订阅以便后续取消
    const subscriptionId = subscription.id
    this.subscriptions.set(subscriptionId, subscription)
    
    return subscriptionId
  }

  /**
   * 订阅用户私有消息
   * @param {number} userId - 用户ID
   * @param {Function} callback - 接收消息的回调函数
   * @returns {string} 订阅ID
   */
  subscribeUserNotifications(userId, callback) {
    return this.subscribe(`/user/${userId}/notification`, callback)
  }

  /**
   * 订阅广播消息
   * @param {Function} callback - 接收消息的回调函数
   * @returns {string} 订阅ID
   */
  subscribeBroadcast(callback) {
    return this.subscribe('/topic/broadcast', callback)
  }

  /**
   * 取消订阅
   * @param {string} subscriptionId - 订阅ID
   */
  unsubscribe(subscriptionId) {
    const subscription = this.subscriptions.get(subscriptionId)
    if (subscription) {
      subscription.unsubscribe()
      this.subscriptions.delete(subscriptionId)
    }
  }

  /**
   * 发送消息
   * @param {string} destination - 目标地址
   * @param {Object} message - 消息内容
   */
  send(destination, message) {
    if (!this.connected || !this.stompClient) {
      console.error('WebSocket未连接')
      return
    }

    this.stompClient.send(destination, {}, JSON.stringify(message))
  }

  /**
   * 断开连接
   */
  disconnect() {
    if (this.stompClient) {
      // 取消所有订阅
      this.subscriptions.forEach((subscription) => {
        subscription.unsubscribe()
      })
      this.subscriptions.clear()

      // 断开连接
      this.stompClient.disconnect(() => {
        console.log('WebSocket已断开')
        this.connected = false
      })
    }
  }

  /**
   * 检查连接状态
   * @returns {boolean}
   */
  isConnected() {
    return this.connected
  }
}

// 创建单例实例
const webSocketService = new WebSocketService()

export default webSocketService

/**
 * 测试发送WebSocket通知（HTTP接口）
 * @param {Object} params
 * @param {number} params.userId - 用户ID
 * @param {string} params.message - 消息内容
 * @returns {Promise}
 */
export function testWebSocketNotification(params) {
  const request = require('./request').default
  return request({
    url: '/ws/notification/test',
    method: 'get',
    params
  })
}
